home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1996 March / macformat-035.iso / CodeWarrior Lite 1.4 / MacOS Examples / AboutBox / About.c next >
Encoding:
Text File  |  1994-11-23  |  26.2 KB  |  902 lines  |  [TEXT/CWIE]

  1. /************************************************************************/
  2. /*    Project...: C++ and ANSI-C Compiler Environment                     */
  3. /*    Name......: MWAbout.c                                                */
  4. /*    Purpose...: about box                                                */
  5. /*    Copyright.: ©Copyright 1993 by metrowerks inc. All rights reserved. */
  6. /************************************************************************/
  7.  
  8. enum  {
  9.     ditl_about = 607,        // about DITL
  10.     ditl_about_items = 8,    // number of items in DITL
  11.     ditl_about_background = 1,    // background about item
  12.     ditl_about_bigbar,        // big tracking bar
  13.     ditl_about_smallbar,    // small tracking bar
  14.     ditl_about_logobox,     // company logo
  15.     ditl_about_namebox,     // company name
  16.     ditl_about_creditsbox,    // credits
  17.     ditl_about_bigbarshadow,    // big bar shadow
  18.     ditl_about_smallbarshadow,    // smallbar shadow
  19.     ditl_about_versionbox,        // version number  +GHD
  20.     ditl_about_helpitem     // hook for ballon help
  21. };
  22.  
  23. #include <GestaltEqu.h>
  24. #include <QDOffscreen.h>
  25. #include <Sound.h>
  26.  
  27. #define        TEXT_AboutVersion    607    
  28. #define        TEXT_Credits        1000
  29.  
  30. #define     WIND_MetroAbout     1000
  31. #define     PICT_Background     1000
  32. #define     PICT_BigBar         1001
  33. #define     PICT_BigBarShadow    2001
  34. #define     PICT_SmallBar        1002
  35. #define     PICT_SmallBarShadow 2002
  36. #define     PICT_LogoBox        3001
  37. #define     PICT_LogoHalf        3002
  38. #define     PICT_LogoWhole        3003
  39. #define     PICT_NameBox        3004
  40. #define     snd_NameBoxClank    3004
  41. #define     Bounce_Distance     10
  42. #define     Fade_Levels         12
  43. typedef struct UserItemRec    {
  44.     long padding1;
  45.     Rect box;
  46.     short padding2;
  47. } UserItemRec;
  48.  
  49. typedef struct DITLRec    {
  50.     short numItems;
  51.     UserItemRec theUserItems[1];
  52. } DITLRec, **DITLHand;
  53.  
  54. void DoAboutBox(Boolean simpleAbout);
  55. void DoSimpleAbout(void);
  56. void SetUpGraphics(void);
  57. void DoAnimation(void);
  58. void CleanUpGraphics(void);
  59. void GetItemRect(short inItem, Rect *outRect);
  60. void DrawPictIntoNewGWorld(short inPICTid, short inDepth,
  61.                            GWorldPtr *outGWorldP);
  62. void DrawTextIntoNewGWorld(short inTEXTid, Rect *inBounds, short inDepth,
  63.                            GWorldPtr *outGWorldP);
  64.  
  65. typedef enum AnimateState  {
  66.     animate_Waiting,
  67.     animate_Active,
  68.     animate_Done
  69. } AnimateState;
  70.  
  71. void MoveOffWorld(GWorldPtr theGWorldP, Rect *currPos, Rect *newPos,
  72.                   Rect *imagePos);
  73. void MoveBar(GWorldPtr theGWorldP, GWorldPtr theShadowWorldP, Rect *inCurrPos,
  74.              Rect *inShadowPos, short inHorizOffset);
  75. void MoveLogoBox(GWorldPtr theGWorldP, Rect *inCurrPos, short inVertOffset);
  76.  
  77. typedef struct BarRec  {
  78.     GWorldPtr theGWorldP;
  79.     GWorldPtr theShadowWorldP;
  80.     Rect currPos;
  81.     Rect shadowPos;
  82. } BarRec;
  83.  
  84. void SetUpBigBar(BarRec *inBigBarRec);
  85. void SetUpSmallBar(BarRec *inSmallBarRec);
  86.  
  87. typedef struct LogoRec    {
  88.     GWorldPtr theGWorldP;
  89.     Rect currPos;
  90.     Rect imagePos;
  91.     short bottomLoc;
  92. } LogoRec;
  93.  
  94. void SetUpLogoBox(LogoRec *inLogoBoxRec);
  95. void SetUpNameBox(LogoRec *inNameBoxRec);
  96.  
  97. typedef struct CreditsRec  {
  98.     GWorldPtr theGWorldP;
  99.     Rect viewRect;
  100.     Rect pictRect;
  101.     short pictHeight;
  102. } CreditsRec;
  103.  
  104. void SetUpCredits(CreditsRec *inCreditsRec);
  105.  
  106. static short Pixel_Depth;
  107. static CWindowPtr aboutBoxWindow;
  108. static PixMapPtr windowPixMapP;
  109. static GWorldPtr drawWorldP;
  110. static PixMapPtr drawPixMapP;
  111. static GWorldPtr backWorldP;
  112. static PixMapPtr backPixMapP;
  113.  
  114. void DoAboutBox(Boolean simpleAbout)
  115. {
  116.     long qdVersion;
  117.     GWorldPtr saveWorld;
  118.     GDHandle saveDevice;
  119.  
  120.     Gestalt(gestaltQuickdrawVersion, &qdVersion);
  121.  
  122.     if (simpleAbout || (qdVersion < gestalt32BitQD) || (FreeMem() < 350000)) {
  123.         GrafPtr savePort;
  124.         //    Machine lacks 32bit QuickDraw or there's not enough memory.
  125.         GetPort(&savePort);
  126.  
  127.         DoSimpleAbout();
  128.  
  129.         SetPort(savePort);
  130.  
  131.     } else {                //    OK to do animated about box.
  132.  
  133.         GetGWorld(&saveWorld, &saveDevice);
  134.  
  135.         SetUpGraphics();
  136.  
  137.         DoAnimation();
  138.  
  139.         CleanUpGraphics();
  140.  
  141.         PurgeMem(maxSize);
  142.         SetGWorld(saveWorld, saveDevice);
  143.     }
  144. }
  145.  
  146. static void DoSimpleAbout(void)
  147. {
  148.     WindowPtr macWindow = GetNewWindow(WIND_MetroAbout, nil, (WindowPtr) -1L);
  149.     PicHandle thePicture;
  150.     Handle theText;
  151.     Rect r;
  152.     long ticks;
  153.  
  154.     ShowWindow(macWindow);
  155.  
  156.     SetPort(macWindow);
  157.  
  158.     thePicture = GetPicture(PICT_Background);
  159.     if (thePicture != nil) {
  160.         r = (**thePicture).picFrame;
  161.  
  162.         DrawPicture(thePicture, &r);
  163.         ReleaseResource((Handle)thePicture);
  164.         
  165.         GetItemRect(ditl_about_versionbox, &r);
  166.         theText = GetResource('TEXT', TEXT_AboutVersion);
  167.         HLock(theText);
  168.         TextSize(9);
  169.         TextFace(bold);
  170.         TextBox(*theText, GetHandleSize(theText), &r, teJustRight);
  171.         ReleaseResource(theText);
  172.         
  173.         Delay(45, &ticks);
  174.  
  175.         thePicture = GetPicture(PICT_LogoWhole);
  176.         GetItemRect(ditl_about_logobox, &r);
  177.         DrawPicture(thePicture, &r);
  178.         ReleaseResource((Handle)thePicture);
  179.         Delay(45, &ticks);
  180.  
  181.         thePicture = GetPicture(PICT_NameBox);
  182.         GetItemRect(ditl_about_namebox, &r);
  183.         DrawPicture(thePicture, &r);
  184.         ReleaseResource((Handle)thePicture);
  185.         Delay(45, &ticks);
  186.  
  187.         while (!Button())
  188.             ;
  189.     }
  190.     DisposeWindow(macWindow);
  191. }
  192.  
  193. static void SetUpGraphics(void)
  194. {
  195.     Rect backRect;
  196.     PixMapHandle thePixMapH;
  197.     Rect versionOffBox, versionWindowBox;
  198.     GWorldPtr    versionWorld;
  199.  
  200.     Pixel_Depth = 8;
  201.  
  202.     //    Make GWorld for offscreen drawing.
  203.  
  204.     GetItemRect(ditl_about_background, &backRect);
  205.     NewGWorld(&drawWorldP, Pixel_Depth, &backRect, nil, nil, 0);
  206.     thePixMapH = GetGWorldPixMap(drawWorldP);
  207.     HLockHi((Handle)thePixMapH);
  208.     LockPixels(thePixMapH);
  209.     drawPixMapP = *thePixMapH;
  210.  
  211.     //    Make GWorld for background.
  212.  
  213.     DrawPictIntoNewGWorld(PICT_Background, Pixel_Depth, &backWorldP);
  214.     thePixMapH = GetGWorldPixMap(backWorldP);
  215.     HLockHi((Handle)thePixMapH);
  216.     LockPixels(thePixMapH);
  217.     backPixMapP = *thePixMapH;
  218.  
  219.     //    Make Window.
  220.  
  221.     aboutBoxWindow = (CWindowPtr) GetNewCWindow(WIND_MetroAbout, nil,
  222.                                                 (WindowPtr) - 1L);
  223.     ShowWindow((WindowPtr)aboutBoxWindow);
  224.     
  225.     HLockHi((Handle)aboutBoxWindow->portPixMap);
  226.     windowPixMapP = *aboutBoxWindow->portPixMap;
  227.  
  228.     //    Draw background in Window.
  229.  
  230.     SetGWorld(aboutBoxWindow, GetMainDevice());
  231.     CopyBits((BitMapPtr)backPixMapP, (BitMapPtr)windowPixMapP, &backRect,
  232.              &backRect, srcCopy, nil);
  233.              
  234.     // Draw Version Number +GHD
  235.     
  236.     GetItemRect(ditl_about_versionbox, &versionWindowBox);
  237.     versionOffBox = versionWindowBox;
  238.     DrawTextIntoNewGWorld(TEXT_AboutVersion, &versionOffBox, Pixel_Depth, &versionWorld);
  239.     LockPixels(GetGWorldPixMap(versionWorld));
  240.     versionWindowBox.bottom = versionWindowBox.top + versionOffBox.bottom;
  241.     CopyBits((BitMapPtr)*GetGWorldPixMap(versionWorld), (BitMapPtr)windowPixMapP, &versionOffBox,
  242.             &versionWindowBox, adMax, nil);
  243.     DisposeGWorld(versionWorld);
  244. }
  245.  
  246. void SetUpBigBar(BarRec *inBigBarRec)
  247. {
  248.     DrawPictIntoNewGWorld(PICT_BigBar, Pixel_Depth, &inBigBarRec->theGWorldP);
  249.     DrawPictIntoNewGWorld(PICT_BigBarShadow, Pixel_Depth,
  250.                           &inBigBarRec->theShadowWorldP);
  251.  
  252.     GetItemRect(ditl_about_bigbar, &inBigBarRec->currPos);
  253.     GetItemRect(ditl_about_bigbarshadow, &inBigBarRec->shadowPos);
  254.  
  255.     OffsetRect(&inBigBarRec->currPos, -inBigBarRec->shadowPos.right, 0);
  256.     OffsetRect(&inBigBarRec->shadowPos, -inBigBarRec->shadowPos.right, 0);
  257. }
  258.  
  259. void SetUpSmallBar(BarRec *inSmallBarRec)
  260. {
  261.     short barWidth;
  262.  
  263.     DrawPictIntoNewGWorld(PICT_SmallBar, Pixel_Depth,
  264.                           &inSmallBarRec->theGWorldP);
  265.     DrawPictIntoNewGWorld(PICT_SmallBarShadow, Pixel_Depth,
  266.                           &inSmallBarRec->theShadowWorldP);
  267.  
  268.     GetItemRect(ditl_about_smallbar, &inSmallBarRec->currPos);
  269.     GetItemRect(ditl_about_smallbarshadow, &inSmallBarRec->shadowPos);
  270.  
  271.     barWidth = inSmallBarRec->currPos.right - inSmallBarRec->currPos.left;
  272.  
  273.     inSmallBarRec->currPos.left = inSmallBarRec->currPos.right;
  274.     inSmallBarRec->currPos.right += barWidth;
  275.  
  276.     OffsetRect(&inSmallBarRec->shadowPos, barWidth, 0);
  277. }
  278.  
  279. void SetUpLogoBox(LogoRec *inLogoBoxRec)
  280. {
  281.     GetItemRect(ditl_about_logobox, &inLogoBoxRec->currPos);
  282.     inLogoBoxRec->bottomLoc = inLogoBoxRec->currPos.bottom;
  283.     OffsetRect(&inLogoBoxRec->currPos, 0, -inLogoBoxRec->currPos.bottom);
  284. }
  285.  
  286. void SetUpNameBox(LogoRec *inNameBoxRec)
  287. {
  288.     DrawPictIntoNewGWorld(PICT_NameBox, Pixel_Depth,
  289.                           &inNameBoxRec->theGWorldP);
  290.  
  291.     GetItemRect(ditl_about_namebox, &inNameBoxRec->currPos);
  292.     inNameBoxRec->bottomLoc = inNameBoxRec->currPos.bottom;
  293.     OffsetRect(&inNameBoxRec->currPos, 0, -inNameBoxRec->currPos.bottom);
  294.     inNameBoxRec->imagePos.left = inNameBoxRec->imagePos.top = 0;
  295.     inNameBoxRec->imagePos.right = inNameBoxRec->currPos.right -
  296.         inNameBoxRec->currPos.left;
  297.     inNameBoxRec->imagePos.bottom = inNameBoxRec->currPos.bottom -
  298.         inNameBoxRec->currPos.top;
  299. }
  300.  
  301. void SetUpCredits(CreditsRec *inCreditsRec)
  302. {
  303.     PicHandle pictureH;
  304.     Rect picFrame;
  305.     PixMapHandle thePixMapH;
  306.     Rect    creditsBox;
  307.  
  308.     //    The only animation is the credits
  309.     //    Therefore, we can reduce the size of the offscreen worlds for the background
  310.     //    and scratch drawing to just cover the area where the credits are drawn.
  311.  
  312.     DisposeGWorld(backWorldP);
  313.     DisposeGWorld(drawWorldP);
  314.  
  315.     GetItemRect(ditl_about_creditsbox, &inCreditsRec->viewRect);
  316.  
  317.     //    Make GWorld for offscreen drawing.
  318.  
  319.     NewGWorld(&drawWorldP, Pixel_Depth, &inCreditsRec->viewRect, nil, nil, 0);
  320.     thePixMapH = GetGWorldPixMap(drawWorldP);
  321.     HLockHi((Handle)thePixMapH);
  322.     LockPixels(thePixMapH);
  323.     drawPixMapP = *thePixMapH;
  324.  
  325.     //    Make GWorld for background.
  326.  
  327.     NewGWorld(&backWorldP, Pixel_Depth, &inCreditsRec->viewRect, nil,
  328.               GetGWorldDevice(drawWorldP), noNewDevice);
  329.     thePixMapH = GetGWorldPixMap(backWorldP);
  330.     HLockHi((Handle)thePixMapH);
  331.     LockPixels(thePixMapH);
  332.     backPixMapP = *thePixMapH;
  333.     SetGWorld(backWorldP, nil);
  334.     pictureH = GetPicture(PICT_Background);
  335.     picFrame = (**pictureH).picFrame;
  336.     DrawPicture(pictureH, &picFrame);
  337.     ReleaseResource((Handle)pictureH);
  338.  
  339.     //    Make GWorld for credits.
  340.     
  341.     creditsBox = inCreditsRec->viewRect;
  342.     DrawTextIntoNewGWorld(TEXT_Credits, &creditsBox,
  343.             Pixel_Depth, &inCreditsRec->theGWorldP);
  344.             
  345.     inCreditsRec->pictRect.left = 0;
  346.     inCreditsRec->pictRect.top = 0;
  347.     inCreditsRec->pictRect.right = inCreditsRec->viewRect.right -
  348.         inCreditsRec->viewRect.left;
  349.     inCreditsRec->pictRect.bottom = inCreditsRec->viewRect.bottom -
  350.         inCreditsRec->viewRect.top;
  351.         
  352.     inCreditsRec->pictHeight = creditsBox.bottom;
  353. }
  354.  
  355. void MoveBar(GWorldPtr theGWorldP, GWorldPtr theShadowWorldP, Rect *inCurrPos,
  356.              Rect *inShadowPos, short inHorizOffset)
  357. {
  358.     Rect exposedRect, coveredRect, imageRect;
  359.     Rect shadowFront, shadowBack;
  360.     PixMapHandle offPixMapH;
  361.  
  362.     //    Draw to the Window.
  363.  
  364.     SetGWorld(aboutBoxWindow, GetMainDevice());
  365.  
  366.     //    Determine areas exposed and covered by bar as it moves.
  367.  
  368.     exposedRect = coveredRect = *inCurrPos;
  369.     shadowFront = shadowBack = *inShadowPos;
  370.     if (inHorizOffset > 0) {
  371.         exposedRect.right = exposedRect.left + inHorizOffset;
  372.         coveredRect.left = coveredRect.right;
  373.         coveredRect.right += inHorizOffset;
  374.         shadowBack.right = shadowBack.left + inHorizOffset;
  375.         shadowBack.top = coveredRect.bottom;
  376.         shadowFront.left = shadowFront.right;
  377.         shadowFront.right += inHorizOffset;
  378.     } else {
  379.         exposedRect.left = exposedRect.right + inHorizOffset;
  380.         exposedRect.bottom = shadowBack.top;
  381.         coveredRect.right = coveredRect.left;
  382.         coveredRect.left += inHorizOffset;
  383.         shadowBack.left = shadowBack.right + inHorizOffset;
  384.         shadowFront.right = shadowFront.left;
  385.         shadowFront.left += inHorizOffset;
  386.         shadowFront.top = coveredRect.bottom;
  387.     }
  388.     imageRect.left = coveredRect.left;
  389.     imageRect.right = coveredRect.right;
  390.     imageRect.top = 0;
  391.     imageRect.bottom = coveredRect.bottom - coveredRect.top;
  392.  
  393.     //    Restore background over exposed area.
  394.  
  395.     CopyBits((BitMapPtr)backPixMapP, (BitMapPtr)windowPixMapP, &exposedRect,
  396.              &exposedRect, srcCopy, nil);
  397.     CopyBits((BitMapPtr)backPixMapP, (BitMapPtr)windowPixMapP, &shadowBack,
  398.              &shadowBack, srcCopy, nil);
  399.  
  400.     //    Draw image at covered area.
  401.  
  402.     offPixMapH = GetGWorldPixMap(theGWorldP);
  403.     LockPixels(offPixMapH);
  404.     CopyBits((BitMapPtr)(*offPixMapH), (BitMapPtr)windowPixMapP, &imageRect,
  405.              &coveredRect, srcCopy, nil);
  406.     UnlockPixels(offPixMapH);
  407.  
  408.     offPixMapH = GetGWorldPixMap(theShadowWorldP);
  409.     LockPixels(offPixMapH);
  410.     CopyBits((BitMapPtr)(*offPixMapH), (BitMapPtr)windowPixMapP, &shadowFront,
  411.              &shadowFront, srcCopy, nil);
  412.     if (inHorizOffset < 0) {
  413.         shadowFront.left = exposedRect.left;
  414.         shadowFront.right = exposedRect.right;
  415.         shadowFront.top = shadowBack.top;
  416.         CopyBits((BitMapPtr)(*offPixMapH), (BitMapPtr)windowPixMapP,
  417.                  &shadowFront, &shadowFront, srcCopy, nil);
  418.     }
  419.     UnlockPixels(offPixMapH);
  420. }
  421.  
  422. void MoveLogoBox(GWorldPtr theGWorldP, Rect *inCurrPos, short inVertOffset)
  423. {
  424.     Rect exposedRect, coveredRect, imageRect;
  425.     RGBColor boxColor =  {
  426.         65535, 52428, 0
  427.     };
  428.  
  429.     //    Draw to the Window.
  430.  
  431.     SetGWorld(aboutBoxWindow, GetMainDevice());
  432.  
  433.     //    Determine areas exposed and covered by bar as it moves.
  434.  
  435.     exposedRect = coveredRect = *inCurrPos;
  436.     if (inVertOffset > 0) {
  437.         exposedRect.bottom = exposedRect.top + inVertOffset;
  438.         coveredRect.top = coveredRect.bottom;
  439.         coveredRect.bottom += inVertOffset;
  440.     } else {
  441.         exposedRect.top = exposedRect.bottom + inVertOffset;
  442.         coveredRect.bottom = coveredRect.top;
  443.         coveredRect.top += inVertOffset;
  444.     }
  445.     imageRect.left = 0;
  446.     imageRect.right = coveredRect.right - coveredRect.left;
  447.     imageRect.top = 0;
  448.     imageRect.bottom = coveredRect.bottom - coveredRect.top;
  449.  
  450.     //    Restore background over exposed area.
  451.  
  452.     CopyBits((BitMapPtr)backPixMapP, (BitMapPtr)windowPixMapP, &exposedRect,
  453.              &exposedRect, srcCopy, nil);
  454.  
  455.     //    Draw image at covered area.
  456.  
  457.     RGBForeColor(&boxColor);
  458.     PaintRect(&coveredRect);
  459.     ForeColor(blackColor);
  460. }
  461.  
  462. void MoveOffWorld(GWorldPtr theGWorldP, Rect *inCurrPos, Rect *inNewPos,
  463.                   Rect *inOffPos)
  464. {
  465.     Rect drawRect;
  466.     PixMapHandle offPixMapH;
  467.  
  468.     //    Create image in draw world.
  469.  
  470.     SetGWorld(drawWorldP, nil);
  471.  
  472.     //    Restore background at current position.
  473.  
  474.     CopyBits((BitMapPtr)backPixMapP, (BitMapPtr)drawPixMapP, inCurrPos,
  475.              inCurrPos, srcCopy, nil);
  476.  
  477.     //    Draw image at new position.
  478.  
  479.     offPixMapH = GetGWorldPixMap(theGWorldP);
  480.     LockPixels(offPixMapH);
  481.     CopyBits((BitMapPtr)(*offPixMapH), (BitMapPtr)drawPixMapP, inOffPos,
  482.              inNewPos, srcCopy, nil);
  483.     UnlockPixels(offPixMapH);
  484.  
  485.     //    Draw union of old and new position to Window.
  486.  
  487.     SetGWorld(aboutBoxWindow, GetMainDevice());
  488.     UnionRect(inCurrPos, inNewPos, &drawRect);
  489.     CopyBits((BitMapPtr)drawPixMapP, (BitMapPtr)windowPixMapP, &drawRect,
  490.              &drawRect, srcCopy, nil);
  491. }
  492.  
  493. static void DoAnimation(void)
  494. {
  495.     BarRec theBigBarRec;
  496.     BarRec theSmallBarRec;
  497.     LogoRec theLogoBoxRec;
  498.     LogoRec theNameBoxRec;
  499.     CreditsRec theCreditsRec;
  500.  
  501.     Rect currPos, imagePos;
  502.  
  503.     PicHandle thePictureH;
  504.     SndChannelPtr theSoundChannelP = nil;
  505.     Handle theSoundH = nil;
  506.  
  507.     AnimateState animBigBar = animate_Active;
  508.     AnimateState animSmallBar = animate_Waiting;
  509.     AnimateState animLogoBoxDown = animate_Waiting;
  510.     AnimateState animLogoBoxUp = animate_Waiting;
  511.     AnimateState animNameBoxDown = animate_Waiting;
  512.     AnimateState animNameBoxUp = animate_Waiting;
  513.     AnimateState animCreditsFade = animate_Waiting;
  514.     AnimateState animCreditsScroll = animate_Waiting;
  515.  
  516.     Boolean logoHalfDrawn = false;
  517.     Boolean logoWholeDrawn = false;
  518.  
  519.     RGBColor fadeColor;
  520.     short grayIndex = 0;
  521.     unsigned short grayLevels[Fade_Levels] =  {
  522.         4369, 8738, 17476, 21845, 30583, 34952, 43690, 48059, 52428, 56979,
  523.         61166, 65535
  524.     };
  525.  
  526.     theBigBarRec.theGWorldP = nil;
  527.     theBigBarRec.theShadowWorldP = nil;
  528.     theSmallBarRec.theGWorldP = nil;
  529.     theSmallBarRec.theShadowWorldP = nil;
  530.     theLogoBoxRec.theGWorldP = nil;
  531.     theNameBoxRec.theGWorldP = nil;
  532.     theCreditsRec.theGWorldP = nil;
  533.  
  534.     SetUpBigBar(&theBigBarRec);
  535.     SetUpLogoBox(&theLogoBoxRec);
  536.     theSoundH = GetResource('snd ', snd_NameBoxClank);
  537.     theSmallBarRec.currPos.left = 1000;
  538.  
  539.     while (!Button()) {
  540.         long ticks;
  541.         long endTicks;
  542.         long startTicks = TickCount();
  543.  
  544.         if ((animLogoBoxDown == animate_Waiting) &&
  545.             (theBigBarRec.currPos.left > 100)) {
  546.             animLogoBoxDown = animate_Active;
  547.         }
  548.         if ((animLogoBoxDown == animate_Active) &&
  549.             (theLogoBoxRec.currPos.bottom >=
  550.              theLogoBoxRec.bottomLoc + Bounce_Distance)) {
  551.             animLogoBoxDown = animate_Done;
  552.             animLogoBoxUp = animate_Active;
  553.         }
  554.         if ((animLogoBoxUp == animate_Active) &&
  555.             (theLogoBoxRec.currPos.bottom <= theLogoBoxRec.bottomLoc)) {
  556.             animLogoBoxUp = animate_Done;
  557.         }
  558.         if ((animBigBar == animate_Active) && !logoHalfDrawn &&
  559.             (theBigBarRec.currPos.right > theLogoBoxRec.currPos.right)) {
  560.             SetGWorld(backWorldP, nil);
  561.             thePictureH = GetPicture(PICT_LogoHalf);
  562.             DrawPicture(thePictureH, &theLogoBoxRec.currPos);
  563.             ReleaseResource((Handle)thePictureH);
  564.             logoHalfDrawn = true;
  565.         }
  566.         if ((animBigBar == animate_Active) &&
  567.             theBigBarRec.currPos.left > backWorldP->portRect.right) {
  568.             animBigBar = animate_Done;
  569.             DisposeGWorld(theBigBarRec.theGWorldP);
  570.             theBigBarRec.theGWorldP = nil;
  571.             DisposeGWorld(theBigBarRec.theShadowWorldP);
  572.             theBigBarRec.theShadowWorldP = nil;
  573.             animSmallBar = animate_Active;
  574.             SetUpSmallBar(&theSmallBarRec);
  575.         }
  576.         if ((animSmallBar == animate_Active) && !logoWholeDrawn &&
  577.             (theSmallBarRec.currPos.left < theLogoBoxRec.currPos.left)) {
  578.             SetGWorld(backWorldP, nil);
  579.             thePictureH = GetPicture(PICT_LogoWhole);
  580.             DrawPicture(thePictureH, &theLogoBoxRec.currPos);
  581.             ReleaseResource((Handle)thePictureH);
  582.             logoWholeDrawn = true;
  583.         }
  584.         if ((animNameBoxDown == animate_Waiting) &&
  585.             (theSmallBarRec.currPos.left < 150)) {
  586.             animNameBoxDown = animate_Active;
  587.             SetUpNameBox(&theNameBoxRec);
  588.         }
  589.         if ((animNameBoxDown == animate_Active) &&
  590.             (theNameBoxRec.currPos.bottom >=
  591.              theNameBoxRec.bottomLoc + Bounce_Distance)) {
  592.             animNameBoxDown = animate_Done;
  593.             animNameBoxUp = animate_Active;
  594.         }
  595.         if ((animNameBoxUp == animate_Active) &&
  596.             (theNameBoxRec.currPos.bottom <= theNameBoxRec.bottomLoc)) {
  597.             OSErr err;
  598.             animNameBoxUp = animate_Done;
  599.             DisposeGWorld(theNameBoxRec.theGWorldP);
  600.             theNameBoxRec.theGWorldP = nil;
  601.             if (theSoundH != nil) {
  602.                 err = SndNewChannel(&theSoundChannelP, sampledSynth, initMono,
  603.                                     nil);
  604.                 if (err == noErr)
  605.                     SndPlay(theSoundChannelP, (SndListHandle)theSoundH, true);
  606.             }
  607.         }
  608.         if ((animSmallBar == animate_Active) &&
  609.             (theSmallBarRec.shadowPos.right < backWorldP->portRect.left)) {
  610.             animSmallBar = animate_Done;
  611.             DisposeGWorld(theSmallBarRec.theGWorldP);
  612.             theSmallBarRec.theGWorldP = nil;
  613.             DisposeGWorld(theSmallBarRec.theShadowWorldP);
  614.             theSmallBarRec.theShadowWorldP = nil;
  615.  
  616.             if (theSoundChannelP != nil) {
  617.                 SndDisposeChannel(theSoundChannelP, true);
  618.                 theSoundChannelP = nil;
  619.             }
  620.             if (theSoundH != nil) {
  621.                 ReleaseResource(theSoundH);
  622.                 theSoundH = nil;
  623.             }
  624.             animCreditsFade = animate_Active;
  625.             SetUpCredits(&theCreditsRec);
  626.         }
  627.         if ((animCreditsFade == animate_Active) &&
  628.             (grayIndex >= Fade_Levels)) {
  629.             animCreditsFade = animate_Done;
  630.             Delay(90, &ticks);
  631.             animCreditsScroll = animate_Active;
  632.         }
  633.         if ((animCreditsScroll == animate_Active) &&
  634.             (theCreditsRec.pictRect.top > theCreditsRec.pictHeight)) {
  635.             theCreditsRec.pictRect.top = 1;
  636.             theCreditsRec.pictRect.bottom = theCreditsRec.viewRect.bottom -
  637.                 theCreditsRec.viewRect.top + 1;
  638.         }
  639.         if (animBigBar == animate_Active) {
  640.             MoveBar(theBigBarRec.theGWorldP, theBigBarRec.theShadowWorldP,
  641.                     &theBigBarRec.currPos, &theBigBarRec.shadowPos, 1);
  642.             theBigBarRec.currPos.left++;
  643.             theBigBarRec.currPos.right++;
  644.             theBigBarRec.shadowPos.left++;
  645.             theBigBarRec.shadowPos.right++;
  646.         }
  647.         if (animLogoBoxDown == animate_Active) {
  648.             MoveLogoBox(theLogoBoxRec.theGWorldP, &theLogoBoxRec.currPos, 1);
  649.             theLogoBoxRec.currPos.top++;
  650.             theLogoBoxRec.currPos.bottom++;
  651.         }
  652.         if (animLogoBoxUp == animate_Active) {
  653.             MoveLogoBox(theLogoBoxRec.theGWorldP, &theLogoBoxRec.currPos, -1);
  654.             theLogoBoxRec.currPos.top--;
  655.             theLogoBoxRec.currPos.bottom--;
  656.         }
  657.         if (animSmallBar == animate_Active) {
  658.             MoveBar(theSmallBarRec.theGWorldP, theSmallBarRec.theShadowWorldP,
  659.                     &theSmallBarRec.currPos, &theSmallBarRec.shadowPos, -1);
  660.             theSmallBarRec.currPos.left--;
  661.             theSmallBarRec.currPos.right--;
  662.             theSmallBarRec.shadowPos.left--;
  663.             theSmallBarRec.shadowPos.right--;
  664.         }
  665.         if (animNameBoxDown == animate_Active) {
  666.             currPos = theNameBoxRec.currPos;
  667.             theNameBoxRec.currPos.top++;
  668.             theNameBoxRec.currPos.bottom++;
  669.             imagePos = theNameBoxRec.imagePos;
  670.             MoveOffWorld(theNameBoxRec.theGWorldP, &currPos,
  671.                          &theNameBoxRec.currPos, &imagePos);
  672.         }
  673.         if (animNameBoxUp == animate_Active) {
  674.             currPos = theNameBoxRec.currPos;
  675.             theNameBoxRec.currPos.top--;
  676.             theNameBoxRec.currPos.bottom--;
  677.             imagePos = theNameBoxRec.imagePos;
  678.             MoveOffWorld(theNameBoxRec.theGWorldP, &currPos,
  679.                          &theNameBoxRec.currPos, &imagePos);
  680.         }
  681.         if (animCreditsFade == animate_Active) {
  682.             PixMapHandle thePixMapH;
  683.  
  684.             Delay(3, &ticks);
  685.             SetGWorld(drawWorldP, nil);
  686.  
  687.             thePixMapH = GetGWorldPixMap(theCreditsRec.theGWorldP);
  688.             LockPixels(thePixMapH);
  689.             CopyBits((BitMapPtr)(*thePixMapH), (BitMapPtr)drawPixMapP,
  690.                      &theCreditsRec.pictRect, &theCreditsRec.viewRect,
  691.                      srcCopy, nil);
  692.             UnlockPixels(thePixMapH);
  693.  
  694.             fadeColor.red = fadeColor.blue = fadeColor.green =
  695.                 grayLevels[grayIndex++];
  696.             RGBForeColor(&fadeColor);
  697.             PenMode(adMin);
  698.             PaintRect(&theCreditsRec.viewRect);
  699.             PenMode(patCopy);
  700.             ForeColor(blackColor);
  701.  
  702.             CopyBits((BitMapPtr)backPixMapP, (BitMapPtr)drawPixMapP,
  703.                      &theCreditsRec.viewRect, &theCreditsRec.viewRect, adMax,
  704.                      nil);
  705.  
  706.             SetGWorld(aboutBoxWindow, GetMainDevice());
  707.             CopyBits((BitMapPtr)drawPixMapP, (BitMapPtr)windowPixMapP,
  708.                      &theCreditsRec.viewRect, &theCreditsRec.viewRect,
  709.                      srcCopy, nil);
  710.         }
  711.         if (animCreditsScroll == animate_Active) {
  712.             PixMapHandle thePixMapH;
  713.             short i, j;
  714.             short creditsWidth =
  715.                 theCreditsRec.viewRect.right -theCreditsRec.viewRect.left -1;
  716.             Rect wrapViewRect, wrapPictRect;
  717.  
  718.             SetGWorld(drawWorldP, nil);
  719.  
  720.             theCreditsRec.pictRect.top += 1;
  721.             theCreditsRec.pictRect.bottom += 1;
  722.  
  723.             thePixMapH = GetGWorldPixMap(theCreditsRec.theGWorldP);
  724.             LockPixels(thePixMapH);
  725.             if (theCreditsRec.pictRect.bottom <= theCreditsRec.pictHeight) {
  726.                 CopyBits((BitMapPtr)(*thePixMapH), (BitMapPtr)drawPixMapP,
  727.                          &theCreditsRec.pictRect, &theCreditsRec.viewRect,
  728.                          srcCopy, nil);
  729.             } else {
  730.                 wrapViewRect = theCreditsRec.viewRect;
  731.                 wrapViewRect.top = wrapViewRect.bottom -
  732.                     (theCreditsRec.pictRect.bottom -
  733.                      theCreditsRec.pictHeight);
  734.                 wrapPictRect = theCreditsRec.pictRect;
  735.                 wrapPictRect.top = 0;
  736.                 wrapPictRect.bottom = wrapPictRect.top +
  737.                     (wrapViewRect.bottom - wrapViewRect.top);
  738.                 CopyBits((BitMapPtr)(*thePixMapH), (BitMapPtr)drawPixMapP,
  739.                          &theCreditsRec.pictRect, &theCreditsRec.viewRect,
  740.                          srcCopy, nil);
  741.                 CopyBits((BitMapPtr)(*thePixMapH), (BitMapPtr)drawPixMapP,
  742.                          &wrapPictRect, &wrapViewRect, srcCopy, nil);
  743.             }
  744.             UnlockPixels(thePixMapH);
  745.  
  746.             PenMode(adMin);                    // Fade out at top and fade in at bottom
  747.             j = Fade_Levels - 1;
  748.             for (i = 0; i < j; i++) {
  749.                 fadeColor.red = fadeColor.blue = fadeColor.green =
  750.                     grayLevels[i];
  751.                 RGBForeColor(&fadeColor);
  752.                 MoveTo(theCreditsRec.viewRect.left,
  753.                        theCreditsRec.viewRect.top + i);
  754.                 Line(creditsWidth, 0);
  755.                 MoveTo(theCreditsRec.viewRect.left,
  756.                        theCreditsRec.viewRect.bottom - i - 1);
  757.                 Line(creditsWidth, 0);
  758.             }
  759.             ForeColor(blackColor);
  760.             PenMode(patCopy);
  761.  
  762.             CopyBits((BitMapPtr)backPixMapP, (BitMapPtr)drawPixMapP,
  763.                      &theCreditsRec.viewRect, &theCreditsRec.viewRect, adMax,
  764.                      nil);
  765.             SetGWorld(aboutBoxWindow, GetMainDevice());
  766.             CopyBits((BitMapPtr)drawPixMapP, (BitMapPtr)windowPixMapP,
  767.                      &theCreditsRec.viewRect, &theCreditsRec.viewRect,
  768.                      srcCopy, nil);
  769.         }
  770.         endTicks = TickCount(); //    Timing loop.
  771.         if (endTicks == startTicks) {    //    TickCount must change during each pass thru animation loop.
  772.             while (endTicks == TickCount())
  773.                 ;            //    this puts an upper speed limit on the animation rate.
  774.         }
  775.     }
  776.  
  777.     // Finished animation (user clicked). Flush the mousedown events
  778.  
  779.     FlushEvents(mDownMask | mUpMask | keyDownMask | keyUpMask | autoKeyMask,
  780.                 0);
  781.  
  782.     //    Dispose of all GWorlds (if they haven't already been disposed).
  783.  
  784.     if (theBigBarRec.theGWorldP != nil)
  785.         DisposeGWorld(theBigBarRec.theGWorldP);
  786.     if (theBigBarRec.theShadowWorldP != nil)
  787.         DisposeGWorld(theBigBarRec.theShadowWorldP);
  788.     if (theSmallBarRec.theGWorldP != nil)
  789.         DisposeGWorld(theSmallBarRec.theGWorldP);
  790.     if (theSmallBarRec.theShadowWorldP != nil)
  791.         DisposeGWorld(theSmallBarRec.theShadowWorldP);
  792.     if (theLogoBoxRec.theGWorldP != nil)
  793.         DisposeGWorld(theLogoBoxRec.theGWorldP);
  794.     if (theNameBoxRec.theGWorldP != nil)
  795.         DisposeGWorld(theNameBoxRec.theGWorldP);
  796.     if (theCreditsRec.theGWorldP != nil)
  797.         DisposeGWorld(theCreditsRec.theGWorldP);
  798.  
  799.     if (theSoundChannelP != nil)
  800.         SndDisposeChannel(theSoundChannelP, true);
  801.     if (theSoundH != nil)
  802.         ReleaseResource(theSoundH);
  803. }
  804.  
  805. static void CleanUpGraphics(void)
  806. {
  807.     DisposeGWorld(drawWorldP);
  808.     DisposeGWorld(backWorldP);
  809.     DisposeWindow((WindowPtr)aboutBoxWindow);
  810. }
  811.  
  812. void GetItemRect(short inItem, Rect *outRect)
  813. {
  814.     DITLHand theDITL;
  815.  
  816.     theDITL = (DITLHand) GetResource('DITL', ditl_about);
  817.     *outRect = (**theDITL).theUserItems[inItem - 1].box;
  818. }
  819.  
  820. void DrawPictIntoNewGWorld(short inPICTid, short inDepth,
  821.                            GWorldPtr *outGWorldP)
  822. {
  823.     PicHandle thePicture;
  824.     Rect picFrame;
  825.     GWorldPtr saveWorld;
  826.     GDHandle saveDevice;
  827.     OSErr err;
  828.  
  829.     thePicture = GetPicture(inPICTid);
  830.     picFrame = (**thePicture).picFrame;
  831.  
  832.     err = NewGWorld(outGWorldP, inDepth, &picFrame, nil,
  833.                     GetGWorldDevice(drawWorldP), noNewDevice);
  834.  
  835.     GetGWorld(&saveWorld, &saveDevice);
  836.     SetGWorld (*outGWorldP, nil);
  837.     LockPixels(GetGWorldPixMap(*outGWorldP));
  838.     DrawPicture(thePicture, &picFrame);
  839.     UnlockPixels(GetGWorldPixMap(*outGWorldP));
  840.     SetGWorld(saveWorld, saveDevice);
  841.  
  842.     ReleaseResource((Handle)thePicture);
  843. }
  844.  
  845. void DrawTextIntoNewGWorld(short inTEXTid, Rect *ioBounds, short inDepth,
  846.                            GWorldPtr *outGWorldP)
  847. {
  848.     Handle theText;
  849.     TEHandle    theTE;
  850.     StScrpHandle    theStyle;
  851.     GWorldPtr saveWorld;
  852.     GDHandle saveDevice;
  853.     OSErr err;
  854.     
  855.         // Put Text in a TERecord
  856.     
  857.     TextFont(applFont);    
  858.     TextSize(9);
  859.     theTE = TEStylNew(ioBounds, ioBounds);
  860.     theText = GetResource('TEXT', inTEXTid);
  861.     theStyle = (StScrpHandle) GetResource('styl', inTEXTid);
  862.     HLock(theText);
  863.     HidePen();
  864.     TEStylInsert(*theText, GetHandleSize(theText), theStyle, theTE);
  865.     ShowPen();
  866.     ReleaseResource(theText);
  867.     if (theStyle != nil) {
  868.         ReleaseResource((Handle)theStyle);
  869.     }
  870.     TESetJust(teJustRight, theTE);
  871.     TECalText(theTE);
  872.     
  873.         // Determine height of the Text
  874.  
  875.     ioBounds->right = ioBounds->right - ioBounds->left;
  876.     ioBounds->left = ioBounds->top = 0;
  877.     ioBounds->bottom = TEGetHeight((**theTE).nLines, 0, theTE);
  878.     
  879.         // Create new GWorld that is the height of the Text
  880.     err = NewGWorld(outGWorldP, inDepth, ioBounds, nil,
  881.                     GetGWorldDevice(drawWorldP), noNewDevice);
  882.  
  883.     GetGWorld(&saveWorld, &saveDevice);
  884.     SetGWorld (*outGWorldP, nil);
  885.     LockPixels(GetGWorldPixMap(*outGWorldP));
  886.     
  887.     EraseRect(ioBounds);
  888.  
  889.         // Draw Text inside GWorld
  890.     (**theTE).viewRect = *ioBounds;
  891.     (**theTE).destRect = *ioBounds;
  892.     (**theTE).inPort = (GrafPtr) *outGWorldP;
  893.     TEUpdate(ioBounds, theTE);
  894.     TEDispose(theTE);
  895.     
  896.     InvertRect(ioBounds);            // White letters on black background
  897.  
  898.     UnlockPixels(GetGWorldPixMap(*outGWorldP));
  899.     SetGWorld(saveWorld, saveDevice);
  900. }
  901.  
  902.